/*
    Project: OCMF (Operant Chamber Management Framework)
    Version: 1.0
    Author: Copyright (C) 2010, Samuel Delaney & Andrew Harvey
    Licence:
        This file is part of OCMF.

            OCMF is free software: you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation, either version 3 of the License, or
            (at your option) any later version.

            OCMF is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
            GNU General Public License for more details.

            You should have received a copy of the GNU General Public License
            along with OCMF.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "OcmfServer.h"

OcmfServer::OcmfServer(MainWindow * mainWindow)
{
    //initialize variables
    aborted = false;        //allows the server thread to loop
    isBusy = false;

    //create new instance of the database client class
    dbClient = new DbClient(this);

    //bind new instance of the ParallelPort class to the static pointer in the PortAction class
    PortAction::Port = new ParallelPort(0x379, 0x378);

    //set the owner main window member variable
    ownerMainWindow = mainWindow;

    //start the server server thread
    start(NormalPriority);
}

OcmfServer::~OcmfServer()
{
    //ensure that the spawned thread doesn't get locked doing something after this instance is disposed of
    Abort();

    //delete ParallelPort instance pointed to by static variable in PortAction class
    delete PortAction::Port;

    //delete the database client
    delete dbClient;
}

//runs the server on a separate thread
void OcmfServer::run()
{
    //loop forever
    while(!aborted)
    {
        //wait for client to issue experiment to server
        Experiment * currentExperiment = WaitForExperiment();

        //retreive images referenced by the current experiment from database
        GetExperimentImages(currentExperiment->ImageFileNames);
/*
        //retrieve the screen template refrenced by the current experiment
        currentExperiment->ExperimentScreenTemplate = GetScreenTemplate(currentExperiment->ExperimentScreenTemplate->Name);

        //set the status of the server in the database so the client can monitor progress
        SetServerStatus(OcmfServerStatus::Running);

        //run the experiment
        currentExperiment->Do();

        //create an experiment result from the experiment and add to database
        AddExperimentResult(&Experiment::GetResultBytes());*/
    }

}

Experiment * OcmfServer::WaitForExperiment()
{
    waitForExperimentReturnVar = NULL;

    //loop until the dbClient return an experiment
    while(waitForExperimentReturnVar == NULL){

        //put the server thread to sleep for 10s
        sleep(10);

        //get next experiment from the database
        waitForExperimentReturnVar = dbClient->GetNextExperiment();

        qDebug("still waiting");


    }
    qDebug("exp found");

    return waitForExperimentReturnVar;
}

void OcmfServer::AddExperimentResult(QByteArray * experimentResultBytes)
{
    dbClient->AddExperimentResult(experimentResultBytes);
}

void OcmfServer::SetServerStatus(OcmfServerStatus::Status ocmfServerStatus)
{
    //set the server status in the database
    dbClient->SetServerStatus(ocmfServerStatus, NULL);
}

void OcmfServer::SynchronizeImagesFolder()
{
    //synchronize the images folder in the database
    //dbClient->SynchronizeImagesFolder();
}

void OcmfServer::GetExperimentImages(QStringList imageFileNames)
{
    //get the images from the database
    //dbClient->GetImages(imageFileNames);
}

ScreenTemplate * OcmfServer::GetScreenTemplate(QString name)
{
    //get a screen template from the database
    //getScreenTemplateReturnVar = dbClient->GetScreenTemplate(name);
}

void OcmfServer::Abort()
{
    //stop the server thread by setting the aborted member variable to true - once this is set, it can't be undone
    aborted = true;
}
